package com.winhxd.b2c.customer.api;

import com.winhxd.b2c.common.cache.Cache;
import com.winhxd.b2c.common.constant.*;
import com.winhxd.b2c.common.context.CustomerUser;
import com.winhxd.b2c.common.domain.ResponseResult;
import com.winhxd.b2c.common.domain.customer.enums.CustomerUserEnum;
import com.winhxd.b2c.common.domain.customer.enums.CustomerUserLevelEnum;
import com.winhxd.b2c.common.domain.customer.model.CustomerUserInfo;
import com.winhxd.b2c.common.domain.customer.vo.CustomerUserInfoSimpleVO;
import com.winhxd.b2c.common.domain.message.condition.SMSCondition;
import com.winhxd.b2c.common.domain.message.model.MiniOpenId;
import com.winhxd.b2c.common.domain.system.login.condition.CustomerSendVerificationCodeCondition;
import com.winhxd.b2c.common.domain.system.login.condition.CustomerUserInfoCondition;
import com.winhxd.b2c.common.exception.BusinessException;
import com.winhxd.b2c.common.feign.message.MessageServiceClient;
import com.winhxd.b2c.common.mq.MQDestination;
import com.winhxd.b2c.common.mq.StringMessageSender;
import com.winhxd.b2c.common.util.GeneratePwd;
import com.winhxd.b2c.common.util.JsonUtil;
import com.winhxd.b2c.common.util.MessageSendUtils;
import com.winhxd.b2c.customer.service.CustomerLoginService;
import com.winhxd.b2c.customer.service.DistributorChannelService;
import com.winhxd.b2c.customer.service.DistributorService;
import com.winhxd.b2c.customer.util.ValidateCustomerUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author baishenghu
 * @date 2019年1月8日 上午9:44:11
 * @Description 微信小程序登录Controller
 * @version
 */
@Api(value = "CustomerLogin Controller", tags = "C-Login")
@RestController
@RequestMapping(value = "/api-customer/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class ApiCustomerLoginController extends ValidateCustomerUser {
	private static final Logger logger = LoggerFactory.getLogger(ApiCustomerLoginController.class);

	@Autowired
	private CustomerLoginService customerLoginService;
	@Autowired
	private Cache cache;
	@Autowired
	MessageServiceClient messageServiceClient;
    @Autowired
    StringMessageSender stringMessageSender;
    @Autowired
    DistributorChannelService channelService;
    @Autowired
    private DistributorService distributorService;
    /**
     * @author baishenghu
     * @date 2019年1月8日 下午1:31:45
     * @Description 通过账号验证码登录
     * @param customerUserInfoCondition
     * @return
     */
    @ApiOperation(value = "微信小程序会员登录接口")
    @ApiResponses({ @ApiResponse(code = BusinessCode.CODE_OK, message = "成功"),
            @ApiResponse(code = BusinessCode.CODE_1001, message = "服务器内部异常"),
            @ApiResponse(code = BusinessCode.CODE_1007, message = "参数无效"),
            @ApiResponse(code = BusinessCode.CODE_1018, message = "网络请求超时"),
            @ApiResponse(code = BusinessCode.CODE_200011, message = "您的账号存在异常行为，已被冻结，如有疑问请联系客服4006870066。") })
    @RequestMapping(value = "customer/security/2056/v1/weChatLogin", method = RequestMethod.POST)
    public ResponseResult<CustomerUserInfoSimpleVO> weChatLogin(@RequestBody CustomerUserInfoCondition customerUserInfoCondition) {
        String logTitle = "=/api-customer/customer/security/2056/v1/weChatLogin-C端小程序登录接口=";
        logger.info("{} -微信小程序登录, 参数：CustomerUserInfoCondition={}", logTitle, JsonUtil.toJSONString(customerUserInfoCondition));
        if (null == customerUserInfoCondition) {
            throw new BusinessException(BusinessCode.CODE_1007);
        }
        ResponseResult<CustomerUserInfoSimpleVO> result = new ResponseResult<>();
        //拿code去换session_key
        ResponseResult<MiniOpenId> object;
        try {
            object = messageServiceClient.getMiniOpenId(customerUserInfoCondition.getCode());
        } catch (Exception e) {
            logger.error("weChatLogin微信登录code获取openId异常失败：", e);
            throw new BusinessException(BusinessCode.CODE_1001);
        }
        if (CustomerConstant.DEFAULT_STATUS != object.getCode()) {
            logger.info("{} - 错误码 {} ,获取微信OpenId异常", logTitle,object.getCode());
            throw new BusinessException(BusinessCode.CODE_1033);
        }
        MiniOpenId mini = object.getData();
        CustomerUserInfoCondition condition = new CustomerUserInfoCondition();
        condition.setOpenid(mini.getOpenid());
        CustomerUserInfo customer = customerLoginService.getCustomerUserInfoByCondition(condition);
        CustomerUserInfoSimpleVO vo = new CustomerUserInfoSimpleVO();
        if (null == customer) {
            //新用户
            vo.setOpenid(mini.getOpenid());
            vo.setSessionKey(mini.getSessionKey());
            vo.setWechatImg("");
            vo.setWechatName("");
        } else {
            if(CustomerUserEnum.CUSTOMER_STATUS_0.getCode().intValue()==customer.getStatus().intValue()){
                logger.info("您的账号-{}-存在异常行为，已被冻结，如有疑问请联系客服4006870066。", condition.getCustomerMobile());
                throw new BusinessException(BusinessCode.CODE_200011);
            }
            //老用户
            vo = customerLoginService.getCustomerUserInfoSimpleVO(customer);
        }
        result.setData(vo);
        return result;
    }
	/**
	 * @author baishenghu
	 * @date 2019年1月8日 下午1:31:45
	 * @Description 通过账号验证码登录
	 * @param condition
	 * @return
	 */
	@ApiOperation(value = "微信小程序会员注册、绑定手机号开店接口")
	@ApiResponses({ @ApiResponse(code = BusinessCode.CODE_OK, message = "成功"),
			@ApiResponse(code = BusinessCode.CODE_1001, message = "服务器内部异常"),
			@ApiResponse(code = BusinessCode.CODE_1019, message = "验证码错误"),
			@ApiResponse(code = BusinessCode.CODE_1007, message = "参数无效"),
			@ApiResponse(code = BusinessCode.CODE_1018, message = "网络请求超时"),
			@ApiResponse(code = BusinessCode.CODE_200011, message = "您的账号存在异常行为，已被冻结，如有疑问请联系客服4006870066。") })
	@RequestMapping(value = "customer/security/2057/v1/weChatRegister", method = RequestMethod.POST)
	public ResponseResult<CustomerUserInfoSimpleVO> weChatRegister(@RequestBody CustomerUserInfoCondition condition) {
        String logTitle = "=/api-customer/customer/security/2056/v1/weChatRegister-C端小程序注册接口=";
        logger.info("{} -微信小程序注册, 参数：CustomerUserInfoCondition={}", logTitle, JsonUtil.toJSONString(condition));
		if (null == condition) {
			throw new BusinessException(BusinessCode.CODE_1007);
		}
		ResponseResult<CustomerUserInfoSimpleVO> result = new ResponseResult<>();
		CustomerUserInfoSimpleVO vo ;

        if(StringUtils.isNotEmpty(condition.getCustomerMobile()) && CustomerUserEnum.CUSTOMER_BIND_1.getCode().intValue()==condition.getRegType().intValue()){
            if (!condition.getVerificationCode().equals(cache
                    .get(CacheName.CUSTOMER_USER_SEND_VERIFICATION_CODE + condition.getCustomerMobile()))) {
                logger.info("{} - ,验证码错误", logTitle);
                throw new BusinessException(BusinessCode.CODE_1019);
            }
            if(null==condition.getCustomerId()){
                CustomerUser currentUser = validateCustomerUser();
                condition.setCustomerId(currentUser.getCustomerId());
            }
            //二级会员绑定手机号，自动开店，自动注册后台账号
            vo = bindCustomerMobile(condition);
        }else if(CustomerUserEnum.CUSTOMER_REG_0.getCode().intValue()==condition.getRegType().intValue()){
            //新用户注册
            vo = regCustomerUserInfo(condition);
        }else{
            logger.info("{} - ,参数异常", logTitle);
            throw new BusinessException(BusinessCode.CODE_1007);
        }
		result.setData(vo);
		return result;
	}

    /**
     * @author baishenghu
     * @date 2019年1月8日 下午1:31:45
     * @Description 通过账号发送验证码
     * @param customerUserInfoCondition
     * @return 验证码
     */
    @ApiOperation(value = "发送验证码")
    @ApiResponses({ @ApiResponse(code = BusinessCode.CODE_OK, message = "成功"),
            @ApiResponse(code = BusinessCode.CODE_1001, message = "服务器内部异常"),
            @ApiResponse(code = BusinessCode.CODE_1020, message = "验证码超时"),
            @ApiResponse(code = BusinessCode.CODE_1007, message = "参数无效") })
    @RequestMapping(value = "customer/security/2059/v1/sendVerification", method = RequestMethod.POST)
    public ResponseResult<String> sendVerification(
            @RequestBody CustomerSendVerificationCodeCondition customerUserInfoCondition) {
        String logTitle = "=/api-customer/customer/security/2059/v1/sendVerification-C端通过账号发送验证码接口=";
        logger.info("{} - 发送验证码, 参数：customerUserInfoCondition={}", logTitle, JsonUtil.toJSONString(customerUserInfoCondition));
        if (null == customerUserInfoCondition) {
            throw new BusinessException(BusinessCode.CODE_1007);
        }
        ResponseResult<String> result = new ResponseResult<>();
        if (cache.exists(
                CacheName.SEND_VERIFICATION_CODE_REQUEST_TIME + customerUserInfoCondition.getCustomerMobile())) {
            logger.info("{} - 发送验证码未超过一分钟", logTitle);
            throw new BusinessException(BusinessCode.CODE_1020);
        }
        /**
         * 随机生成6位数验证码
         */
        String verificationCode = GeneratePwd.generatePwd6Mobile();
        cache.set(CacheName.CUSTOMER_USER_SEND_VERIFICATION_CODE + customerUserInfoCondition.getCustomerMobile(),
                verificationCode);
        cache.expire(CacheName.CUSTOMER_USER_SEND_VERIFICATION_CODE + customerUserInfoCondition.getCustomerMobile(),
                AppConstant.SEND_SMS_EXPIRE_SECOND);
        /**
         * 60秒以后调用短信服务
         */
        cache.set(CacheName.SEND_VERIFICATION_CODE_REQUEST_TIME + customerUserInfoCondition.getCustomerMobile(),
                verificationCode);
        cache.expire(CacheName.SEND_VERIFICATION_CODE_REQUEST_TIME + customerUserInfoCondition.getCustomerMobile(),
                AppConstant.REQUEST_SEND_SMS_EXPIRE_SECOND);

        /**
         * 发送模板内容
         */
        String content = String.format(SendSMSTemplate.SMSCONTENT, verificationCode);
        SMSCondition sMSCondition = new SMSCondition();
        sMSCondition.setContent(content);
        sMSCondition.setTelePhoneNo(customerUserInfoCondition.getCustomerMobile());
        String sms = JsonUtil.toJSONString(sMSCondition);
        stringMessageSender.send(MQDestination.SMS_MESSAGE, sms);
        logger.info(customerUserInfoCondition.getCustomerMobile() + ":发送的内容为:" + content);
        return result;
    }

    /**
     * 添加数盟id
     * @param customerUserInfoCondition
     * @return
     */
    @ApiOperation(value = "微信小程序添加数盟id")
    @ApiResponses({@ApiResponse(code = BusinessCode.CODE_OK, message = "成功"),
            @ApiResponse(code = BusinessCode.CODE_1001, message = "服务器内部异常"),
            @ApiResponse(code = BusinessCode.CODE_1007, message = "参数无效")})
    @RequestMapping(value = "customer/2060/v1/addDigitalUnionId", method = RequestMethod.POST)
    public ResponseResult<Boolean> addDigitalUnionId(@RequestBody CustomerUserInfoCondition customerUserInfoCondition) {
        String logTitle = "=/api-customer/customer/2060/v1/addDigitalUnionId-C端小程序添加数盟id接口=";
        logger.info("{} -微信小程序添加数盟id, 参数：customerUserInfoCondition={}", logTitle, JsonUtil.toJSONString(customerUserInfoCondition));

        CustomerUserInfo customerUserInfo = customerLoginService.getCustomerUserInfoById(customerUserInfoCondition.getCustomerId());
        validateCustomerUserInfo(customerUserInfo);
        if(null != customerUserInfo) {
            if (CustomerUserLevelEnum.CUSTOMER_LEVEL_0.getCode().intValue() == customerUserInfo.getLevel().intValue()) {
                String key = CustomerConstant.USER_TODAY_VISIT_COUNT + customerUserInfo.getParentId();
                cache.del(key);
            }
        }else{
            if (StringUtils.isBlank(customerUserInfoCondition.getDigitalUnionId())) {
                throw new BusinessException(BusinessCode.CODE_1007);
            }
            CustomerUser currentCustomerUser = validateCustomerUser();
            customerUserInfo = new CustomerUserInfo();
            customerUserInfo.setId(currentCustomerUser.getCustomerId());
            customerUserInfo.setDigitalUnionId(customerUserInfoCondition.getDigitalUnionId());
            int num = customerLoginService.updateCustomerInfo(customerUserInfo);
            boolean flag = num == 1 ? true : false;
        }
        ResponseResult<Boolean> result = new ResponseResult<>();
        result.setData(true);
        return result;
    }

	/**
	 *	绑定手机号 开店
	 * @param condition
	 * @return
	 */
	private CustomerUserInfoSimpleVO bindCustomerMobile( CustomerUserInfoCondition condition) {
        CustomerUserInfo customer = customerLoginService.getCustomerUserInfoById(condition.getCustomerId());
        validateCustomerUserInfo(customer);
        customerLoginService.checkMobileAndAccount(customer.getId(),condition.getCustomerMobile());
		if(CustomerUserEnum.CUSTOMER_STATUS_0.getCode().intValue()==customer.getStatus().intValue()){
			logger.info("您的账号-{}-存在异常行为，已被冻结，如有疑问请联系客服4006870066。", condition.getCustomerMobile());
            throw new BusinessException(BusinessCode.CODE_200011);
        }
        if(CustomerUserLevelEnum.CUSTOMER_LEVEL_1.getCode().intValue()==customer.getLevel().intValue()){
            logger.info("您的账号-{}-存在异常行为，一级经销商无法开店:{}，如有疑问请联系客服4006870066。", condition.getCustomerMobile(),customer.getLevel());
            throw new BusinessException(BusinessCode.CODE_200025);
        }
        CustomerUserInfo userParent;
        if(null!=condition.getShareCustomerId()) {
            userParent = customerLoginService.getCustomerUserInfoById(condition.getShareCustomerId());
            if(CustomerUserLevelEnum.CUSTOMER_LEVEL_2.getCode().intValue()==customer.getLevel().intValue()){
                logger.info("您的账号-{}-存在异常行为，您已经是二级经销商:{}，如有疑问请联系客服4006870066。", condition.getCustomerMobile(),customer.getLevel());
                throw new BusinessException(BusinessCode.CODE_200025);
            }
            if(CustomerUserLevelEnum.CUSTOMER_LEVEL_1.getCode().intValue()!=userParent.getLevel().intValue()){
                logger.info("您的账号-{}-存在异常行为，您的上级必须是一级经销商:{}，如有疑问请联系客服4006870066。", condition.getCustomerMobile(),customer.getLevel());
                throw new BusinessException(BusinessCode.CODE_200025);
            }
        }else{
            userParent = customerLoginService.getCustomerUserInfoById(customer.getParentId());
        }
        validateCustomerUserInfo(userParent);
        CustomerUserInfoCondition customerUserMobile = new CustomerUserInfoCondition();
        customerUserMobile.setCustomerMobile(condition.getCustomerMobile());
        CustomerUserInfo customerMobile = customerLoginService.getCustomerUserInfoByCondition(customerUserMobile);
        if(null!=customerMobile && !customerMobile.getOpenid().equals(customer.getOpenid())){
            logger.info("您的账号-{}-存在异常行为，会员手机号存在异常:{}，如有疑问请联系客服4006870066。", condition.getCustomerMobile(),userParent.getLevel());
            throw new BusinessException(BusinessCode.CODE_200025);
        }
        cache.del(CacheName.CUSTOMER_USER_INFO_TOKEN + customer.getToken());
        customer.setCustomerMobile(condition.getCustomerMobile());
        customer.setUpdated(new Date());
        customer.setUpdatedByName(customer.getWechatName());
        customer.setUpdatedBy(customer.getId());
        customer.setLevel(CustomerUserLevelEnum.CUSTOMER_LEVEL_2.getCode());
        customer.setToken(GeneratePwd.getRandomUUID());
        customer.setParentId(userParent.getId());
        customer.setChannelId(userParent.getChannelId());
        customer.setBindStatus(CustomerConstant.BIND_STATUS_OK);
        customer.setStoreOpenCodeUrl("");
        customer.setCustomerStoreCodeUrl("");
        customer.setBindTime(new Date());
        //开店信息
        customer.setStoreName(customer.getWechatName() + "的小店");
        customer.setStoreStatus(CustomerConstant.OPEN_STATUS);

        // 初始化管理平台账号
        String customerString = JsonUtil.toJSONString(customer);
        distributorService.verfySysUserMobile(condition.getCustomerMobile(),customer.getId());
        stringMessageSender.send(MQDestination.INIT_SYS_USER_MESSAGE, customerString);
		customerLoginService.updateCustomerInfo(customer);
        // 换绑 操作  因为自己升级为二级经销商
        stringMessageSender.send(MQDestination.UPDATE_CUSTOMER_PARENT_ID_MESSAGE, String.valueOf(customer.getId()));
        CustomerUserInfo userOutlet = customerLoginService.findCustomerUserByLevel();
        if(userOutlet.getId().equals(customer.getParentId())) {
            //保存会员原始关系
            customerLoginService.bindOriginalRelation(userParent.getId(), userParent.getOpenid(), customer);
        }
		return customerLoginService.getCustomerUserInfoSimpleVO(customer);
	}

	/**
	 *  注册会员
	 * @param condition
	 * @return
	 */
	private CustomerUserInfoSimpleVO regCustomerUserInfo( CustomerUserInfoCondition condition) {
        CustomerUserInfo customerUserInfo;
        CustomerUserInfoCondition conditionOpenId= new CustomerUserInfoCondition();
        conditionOpenId.setOpenid(condition.getOpenid());
        customerUserInfo = customerLoginService.getCustomerUserInfoByCondition(conditionOpenId);
        if(customerUserInfo==null) {
            CustomerUserInfo userParent;
            CustomerUserInfo outlet = customerLoginService.findCustomerUserByLevel();
            String openId="";
            if(null!=condition.getShareCustomerId()) {
                userParent = customerLoginService.getCustomerUserInfoById(condition.getShareCustomerId());
                openId=userParent.getOpenid();
                if(CustomerUserLevelEnum.CUSTOMER_LEVEL_0.getCode().intValue()==userParent.getLevel().intValue()){
                    userParent = customerLoginService.getCustomerUserInfoById(userParent.getParentId());
                }
            }else{
                userParent = outlet;
            }
            validateCustomerUserInfo(userParent);
            String key = condition.getOpenid();
            Long nxFlag = cache.setnx(key,key);
            if (nxFlag==1L) {
                cache.expire(key,CacheName.CACHE_NX_SECOND);
            }else{
                logger.info("您的重复保存会员信息OpenId:{}，如有疑问请联系客服4006870066。",condition.getOpenid());
                throw new BusinessException(BusinessCode.CODE_1034);
            }
            //new 里面初始化默认数据
            customerUserInfo = new CustomerUserInfo(condition.getOpenid());
            customerUserInfo.setSessionKey(condition.getSessionKey());
            customerUserInfo.setHeadImg(condition.getHeadImg());
            customerUserInfo.setWechatName(condition.getNickName());
            customerUserInfo.setToken(GeneratePwd.getRandomUUID());
            customerUserInfo.setChannelId(userParent.getChannelId());
            customerUserInfo.setNickName(condition.getNickName());
            customerUserInfo.setCreatedByName(condition.getNickName());
            customerUserInfo.setParentId(userParent.getId());
            customerLoginService.saveLoginInfo(customerUserInfo);
            if(null!=condition.getShareCustomerId()) {
                //保存会员原始关系
               customerLoginService.bindOriginalRelation(condition.getShareCustomerId(),openId,customerUserInfo);
            }
        }
		return customerLoginService.getCustomerUserInfoSimpleVO(customerUserInfo);
	}

}
